/* Soubor je ulozen v kodovani UTF-8.
 * Kontrola kódování: Příliš žluťoučký kůň úpěl ďábelské ódy. */

package cz.vse.adventura.po1715.xforv00_forejt.hra;

import cz.pecinovsky.english.pojj.adv_framework.game_gui.IBagG;
import cz.pecinovsky.english.pojj.adv_framework.game_txt.ICommand;
import cz.pecinovsky.english.pojj.adv_framework.game_gui.IGameG;
import cz.pecinovsky.english.pojj.adv_framework.game_gui.IListener;
import cz.pecinovsky.english.pojj.adv_framework.game_gui.IPlaceG;
import cz.pecinovsky.english.pojj.adv_framework.game_gui.Commands;
import cz.pecinovsky.english.pojj.adv_framework.scenario.AScenarioManager;
import cz.vse.adventura.po1715.xforv00_forejt.SprávceScénářůL;
import cz.vse.adventura.po1715.xforv00_forejt.data.DataPkg;
import java.net.URL;
import java.util.Collection;
import javax.swing.ImageIcon;

import static cz.vse.adventura.po1715.xforv00_forejt.hra.Texty.*;





/*******************************************************************************
 * Instance třídy {@code Hra} představuje hlavní prostřední pro hru
 *
 * @author    jméno autora
 * @version   0.00.000
 */
public class Hra implements IGameG
{
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================

    private static final Commands příkazy =
            new Commands(pJDI, pPOLOŽ, pVEZMI, pKONEC);



//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================

    /*
     * Obsahuje odkaz na aktuální hru
     */
    private static Hra hra = new Hra();

    private final AScenarioManager správceScénářů = new SprávceScénářůL();

    private SprávceMístností správceMístností = SprávceMístností.getSprávceMístností();
//    private final SprávceMístností správceMístností = new SprávceMístností();

//== STATICKÝ INICIALIZAČNÍ BLOK - STATICKÝ KONSTRUKTOR ========================
//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================
//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ TŘÍDY ========================================

   

//== OSTATNÍ NESOUKROMÉ METODY TŘÍDY ===========================================
//##############################################################################
//== KONSTRUKTORY A TOVÁRNÍ METODY =============================================

    /***************************************************************************
     * SOukromý konstruktor
     */
    private Hra()
    {
        správceScénářů.setGame(this);
        správceMístností.inicializuj();
    }

    public static Hra getHra()
    {
        return hra;
    }


//== ABSTRAKTNÍ METODY =========================================================
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ INSTANCÍ =====================================
 /***************************************************************************
     * Vrátí jméno autora scénáře ve formátu "PŘÍJMENÍ Křestní",
     * tj. neprve příjmení psané velkými písmeny a za ním křestní jméno,
     * u nějž bude velké pouze první písmeno a ostatní písmena budou malá.
     *
     * @return Jméno autora/autorky programu ve tvaru PŘÍJMENÍ Křestní
     */
    @Override
    public String getAuthor()
    {
        return správceScénářů.getAuthor();
    }


    /***************************************************************************
     * Vrátí x-name autora/autorky programu zapsané velkými písmeny.<p>
     * X-name má tvar <b>{@code XPPPK99}</b> nebo <b>{@code XPPPK999}</b>,
     * kde<br>
     * <ul>
     *   <li><b>{@code PPP}</b> zastupuje první tří písmena příjmení autora(ky)
     *      zapsaná velkými písmeny, </li>
     *   <li><b>{@code K}</b> zastupuje první písmeno křestního jména a </li>
     *   <li><b>{@code 99}</b>, resp. <b>{@code 999}</b> zastupují číslice
     *      přiřazené systémem, pomocí nichž se rozsliší studenti(ky)
     *      s předchozími znaky shodnými.
     * </ul>
     *
     * @return X-name autora/autorky programu
     */
    @Override
    public String getXNAME()
    {
        return správceScénářů.getXNAME();
    }

    /***************************************************************************
     * Vrátí odkaz na aktuální místnost,
     * tj. na místnost, v niž se pravé nachází hráč.
     *
     * @return Požadovaný odkaz
     */
    @Override
    public Místnost getActualPlace()
    {
        return správceMístností.getAktuálníProstor();
    }

    /***************************************************************************
     * Nastaví aktuální prostor na požadovanou místnost
     */
    
    void setActualPlace(Místnost název)
    {
        správceMístností.setAktuálníProstor(název);
    }

    /***************************************************************************
     * Vrátí odkaz na místnost podle zadaného názvu
     *
     * @return Požadovaný odkaz
     */

    Místnost getPlace(String název)
    {
        return správceMístností.getMístnost(název);
    }


    /***************************************************************************
     * Vrátí odkaz na batoh, do nějž bude hráč ukládat sebrané předměty.
     *
     * @return Požadovaný odkaz
     */
    @Override
    public Batoh getBag()
     {
         return Batoh.getBatoh();
     }


    /***************************************************************************
     * Vrátí kolekci odkazů na jednotlivé místnosti.
     *
     * @return Požadovaná kolekce
     */
    @Override
    public Collection<? extends IPlaceG> getAllPlaces()
     {
         return správceMístností.getMístnosti();
     }


    /***************************************************************************
     * Vrátí kolekci všech příkazů použitelných ve hře.
     *
     * @return Požadovaná kolekce
     */
    @Override
    public Collection<? extends ICommand> getAllCommands()
     {
       return APříkaz.getPříkazy();
     }


    /***************************************************************************
     * Vrátí true, pokud je hra již ukončena.
     *
     * @return Požadovaná informace
     */
    @Override
    public boolean isReady()
     {
        return APříkaz.isSkončeno();
     }


    /***************************************************************************
     * Vrátí správce scénářů, které umožní prověřit funkčnost hry
     * a/nebo demonstrovat její průběh.
     *
     * @return Správce scénářů dané hry
     */
    @Override
    public AScenarioManager getScenarioManager()
     {
         return správceScénářů;
     }

    /***************************************************************************
     * Vrátí vstupní znakový proud obsahující stránku s nápovědou.
     *
     * @return Požadovaný odkaz
     */
    @Override
    public URL getHelpURL()
    {
        Class<DataPkg> classDataPkg = DataPkg.class;  //Musí být ve stejném bal. jako help.html
        URL url = classDataPkg.getResource("help.html");
        return url;
    }

    /***************************************************************************
     * Vrátí obrázek s plánkem prostoru, v němž se hraje.
     *
     * @return Požadovaný odkaz
     */
    @Override
    public ImageIcon getMap()
    {
        URL url = DataPkg.class.getResource("plan.png");
        ImageIcon plan = new ImageIcon(url);
        return plan;
    }

    /***************************************************************************
     * Vrátí odkaz na přepravku s názvy příkazů pro přesun do jiné místnosti,
     * zvednutí předmětu a jeho položení.
     *
     * @return Požadovaný odkaz
     */
    @Override
    public Commands getBasicCommands()
{
         return příkazy;
}


//== OSTATNÍ NESOUKROMÉ METODY INSTANCÍ ========================================


    /***************************************************************************
     * Ukončí celou hru a vrátí alokované prostředky.
     */
    @Override
    public void stop()
     {
        APříkaz.konec();
     }


    /***************************************************************************
     * Zpracuje zadaný příkaz a vrátí text zprávy pro uživatele.
     *
     * @param prikaz Zadávaný příkaz
     * @return Textová odpověď hry na zadaný příkaz
     */
    @Override
    public String executeCommand( String prikaz )
    {
        return APříkaz.zpracujPříkaz(prikaz);
    }



    /***************************************************************************
     * Přidá zadaného posluchače do seznamu posluchačů,
     * které zpravuje o změně množiny předmětů v batohu.
     *
     * @param listener Přihlašovaný posluchač
     */
    @Override
    public void addBagListener(IListener<IBagG> listener)
    {
         Batoh.getBatoh().addListener(listener);
    }

     /***************************************************************************
     * Odebere zadaného posluchače ze seznamu posluchačů,
     * které zpravuje o změně množiny předmětů v batohu.
     *
     * @param listener Odhlašovaný posluchač
     */
    @Override
    public void removeBagListener(IListener<IBagG> listener)
    {
         Batoh.getBatoh().removeListener(listener);
    }


    /***************************************************************************
     * Přidá zadaného posluchače do seznamu posluchačů,
     * které zpravuje o změně množiny předmětů v aktuální místnosti.
     *
     * @param listener Přihlašovaný posluchač
     */
    @Override
    public void addObjectListener(IListener<IPlaceG> listener)
    {
         správceMístností.addObjectListener(listener);
    }


    /***************************************************************************
     * Odebere zadaného posluchače ze seznamu posluchačů,
     * které zpravuje o změně množiny předmětů v aktuální místnosti.
     *
     * @param listener Odhlašovaný posluchač
     */
    @Override
    public void removeObjectListener(IListener<IPlaceG> listener)
    {
         správceMístností.removeObjectListener(listener);
    }


    /***************************************************************************
     * Přidá zadaného posluchače do seznamu posluchačů,
     * které zpravuje o změně množiny sousedů aktuální místnosti.
     *
     * @param listener Přihlašovaný posluchač
     */
    @Override
    public void addNeighborsListener(IListener<IPlaceG> listener)
    {
         správceMístností.addNeighborsListener(listener);
    }


    /***************************************************************************
     * Odebere zadaného posluchače ze seznamu posluchačů,
     * které zpravuje o změně množiny sousedů aktuální místnosti.
     *
     * @param listener Odhlašovaný posluchač
     */
    @Override
    public void removeNeighborsListener(IListener<IPlaceG> listener)
    {
         správceMístností.removeNeighborsListener(listener);
    }


    /***************************************************************************
     * Přidá zadaného posluchače do seznamu posluchačů,
     * kterým hra oznamuje začátek a konec rozhovoru.
     *
     * @param listener Přihlašovaný posluchač
     */
    @Override
    public void addDialogListener(IListener<Boolean> listener)
    {
         Rozhovor.addDialogListener(listener);
    }

    /***************************************************************************
     * Odebere zadaného posluchače ze seznamu posluchačů,
     * kterým hra oznamuje začátek a konec rozhovoru.
     *
     * @param listener Odhlašovaný posluchač
     */
    @Override
    public void removeDialogListener(IListener<Boolean> listener)
    {
         Rozhovor.removeDialogListener(listener);
    }

//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================
//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================
//== INTERNÍ DATOVÉ TYPY =======================================================
//== TESTY A METODA MAIN =======================================================
//
//     /***************************************************************************
//      * Testovací metoda.
//      */
//     public static void test()
//     {
//         Hra instance = new Hra();
//     }
//     /** @param args Parametry příkazového řádku - nepoužívané. */
//     public static void main(String[] args)  {  test();  }
}
